package com.ld.shieldsb.dao.model;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Set;

import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource.JoinType;
import com.google.common.collect.ImmutableList;
import com.ld.shieldsb.annotation.field.link.Many2Many;
import com.ld.shieldsb.annotation.util.AnnotationUtil;
import com.ld.shieldsb.annotation.util.TableNameUtil;
import com.ld.shieldsb.common.core.reflect.FunctionUtil;
import com.ld.shieldsb.common.core.reflect.FunctionUtil.Property;
import com.ld.shieldsb.common.core.util.StringUtils;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Data
@Slf4j
public class QueryModel implements Cloneable {

    protected String selectFields = "*";
    protected String condition = "";// 查询条件
    protected String order = "";// 排序条件

    protected Boolean queryLink = false; // 查询级联对象
    protected List<Property<?, ?>> queryLinkFields = null; // 查询哪些级联对象，如果queryLink为true此项不设置默认查询model中配置了@Link注解的

    protected List<Object> params = new ArrayList<>();

    protected List<Condition> cnds = new ArrayList<>(); // 条件
    protected List<Order> orders = new ArrayList<>(); // 排序

    protected String joinTableAlias = null;// 用于join查询用,表别名
    protected JoinType joinType = null; // join类型

    public QueryModel() {
    }

    public QueryModel(String selectFields) {
        this.selectFields = selectFields;
    }

    protected Object formatValue(Object value) {
        if (value != null && value.getClass() == java.util.Date.class) {
            return new java.sql.Timestamp(((Date) value).getTime());
        } else {
            return value;
        }
    }

    public QueryModel(String fieldName, Object value) {
        addEq(fieldName, value);
    }

    public void addEq(String fieldName, Object value) {
        addEq(fieldName, value, true);
    }

    public void addEq(String fieldName, Object value, boolean ignoreNull) {
        if (value == null || (value.equals("") && ignoreNull)) {
            Condition cnd = new Condition(fieldName, Condition.Type.EQUAL, null);
            cnds.add(cnd);
            condition += " AND " + fieldName + " IS NULL";
        } else {
            Condition cnd = new Condition(fieldName, Condition.Type.EQUAL, value);
            cnds.add(cnd);
            condition += " AND " + fieldName + "=?";
            params.add(formatValue(value));
        }
    }

    /**
     * 为查询条件追加左括号
     *
     * @author hansai
     * @date 2019-08-14 14:46
     */
    public void appendLeftParenthesis() {
        condition += " ( ";
    }

    /**
     * 为查询条件追加右括号
     *
     * @author hansai
     * @date 2019-08-14 14:46
     */
    public void appendRightParenthesis() {
        condition += " ) ";
    }

    /**
     * 为查询条件追加 or
     *
     * @author hansai
     * @date 2019-08-08 11:54
     */
    public void appendOr() {
        condition += " OR ";
    }

    /**
     * 调整动态查询条件
     *
     * @author hansai
     * @date 2019-08-08 14:37
     */
    public void adjustmentDynamicCondition() {
        // 1: ( and 替换为 and (
        // 2: or and 替换为 or
        condition = condition.replaceAll("\\s+\\(\\s+(?i)and\\s+", " AND ( ").replaceAll("\\s+(?i)or\\s+(?i)and\\s+", " OR ")
                .replaceAll("\\s+\\(\\s+(?i)and\\s+", " AND ( ");
        if (condition.endsWith("OR ")) {
            condition = condition.substring(0, condition.lastIndexOf("OR "));
        }
    }

    public <T> void addEq(Property<T, ?> property, Object value) {
        addEq(QueryManager.getFunctionName(property), value);
    }

    public void addUnEq(String fieldName, Object value) {
        addUnEq(fieldName, value, true);
    }

    public void addUnEq(String fieldName, Object value, boolean ignoreNull) {
        if (value == null || (value.equals("") && ignoreNull)) {
            Condition cnd = new Condition(fieldName, Condition.Type.NOT_EQUAL, null);
            cnds.add(cnd);
            condition += " AND " + fieldName + " IS NOT NULL";
        } else {
            Condition cnd = new Condition(fieldName, Condition.Type.NOT_EQUAL, value);
            cnds.add(cnd);
            condition += " AND " + fieldName + "!=?";
            params.add(formatValue(value));
        }
    }

    public <T> void addUnEq(Property<T, ?> property, Object value) {
        addUnEq(QueryManager.getFunctionName(property), value);
    }

    // 大于
    public void addGt(String fieldName, Object value) {
        Condition cnd = new Condition(fieldName, Condition.Type.GT, value);
        cnds.add(cnd);
        condition += " AND " + fieldName + ">?";
        params.add(formatValue(value));
    }

    public <T> void addGt(Property<T, ?> property, Object value) {
        addGt(QueryManager.getFunctionName(property), value);
    }

    public void addGe(String fieldName, Object value) {
        Condition cnd = new Condition(fieldName, Condition.Type.GE, value);
        cnds.add(cnd);
        condition += " AND " + fieldName + ">=?";
        params.add(formatValue(value));
    }

    public <T> void addGe(Property<T, ?> property, Object value) {
        addGe(QueryManager.getFunctionName(property), value);
    }

    // 小于
    public void addLt(String fieldName, Object value) {
        Condition cnd = new Condition(fieldName, Condition.Type.LT, value);
        cnds.add(cnd);
        condition += " AND " + fieldName + "<?";
        params.add(formatValue(value));
    }

    public <T> void addLt(Property<T, ?> property, Object value) {
        addLt(QueryManager.getFunctionName(property), value);
    }

    public void addLe(String fieldName, Object value) {
        Condition cnd = new Condition(fieldName, Condition.Type.LE, value);
        cnds.add(cnd);
        condition += " AND " + fieldName + "<=?";
        params.add(formatValue(value));
    }

    public <T> void addLe(Property<T, ?> property, Object value) {
        addLe(QueryManager.getFunctionName(property), value);
    }

    public void addLeftLike(String fieldName, String value) {
        Condition cnd = new Condition(fieldName, Condition.Type.LIKE_LEFT, value);
        cnds.add(cnd);
        condition += " AND " + fieldName + " LIKE ?";
        params.add(value + "%");
    }

    public <T> void addLeftLike(Property<T, ?> property, String value) {
        addLeftLike(QueryManager.getFunctionName(property), value);
    }

    public void addRightLike(String fieldName, String value) {
        Condition cnd = new Condition(fieldName, Condition.Type.LIKE_RIGHT, value);
        cnds.add(cnd);
        condition += " AND " + fieldName + " LIKE ?";
        params.add("%" + value);
    }

    public <T> void addRightLike(Property<T, ?> property, String value) {
        addRightLike(QueryManager.getFunctionName(property), value);
    }

    public void addLike(String fieldName, String value) {
        Condition cnd = new Condition(fieldName, Condition.Type.LIKE, value);
        cnds.add(cnd);
        condition += " AND " + fieldName + " LIKE ?";
        params.add("%" + value + "%");
    }

    public <T> void addLike(Property<T, ?> property, String value) {
        addLike(QueryManager.getFunctionName(property), value);
    }

    public void addRegion(String fieldName, Object value1, Object value2) {
        Condition cnd = new Condition(fieldName, Condition.Type.BETWEEN, ImmutableList.of(value1, value2));
        cnds.add(cnd);
        condition += " AND " + fieldName + " BETWEEN ? AND ?";
        params.add(formatValue(value1));
        params.add(formatValue(value2));
    }

    public <T> void addRegion(Property<T, ?> property, Object value1, Object value2) {
        addRegion(QueryManager.getFunctionName(property), value1, value2);
    }

    public void addInCondition(String fieldName, String subCondition) {
        Condition cnd = new Condition(fieldName, Condition.Type.IN_STR, subCondition);
        cnds.add(cnd);
        condition += " AND " + fieldName + " IN (" + subCondition + ")";
    }

    public <T> void addInCondition(Property<T, ?> property, String subCondition) {
        addInCondition(QueryManager.getFunctionName(property), subCondition);
    }

    public void addInSet(String fieldName, Object[] values) {
        addInSet(fieldName, values, true);
    }

    public <T> void addInSet(Property<T, ?> property, Object[] values) {
        addInSet(QueryManager.getFunctionName(property), values);
    }

    // isContained 是否为包含
    public void addInSet(String fieldName, Object[] values, boolean isContained) {
        Condition cnd = new Condition(fieldName, Condition.Type.IN_SET, values);
        cnds.add(cnd);
        condition += " AND " + getInStr(fieldName, values, isContained);
    }

    private String getInStr(String fieldName, Object[] values, boolean isContained) {
        // 张和祥：添加values数量可能大于1000的处理
        StringBuffer sb = new StringBuffer();
        if (values != null) {

            if (values.length > 1000) {
                log.warn("in 参数超过1000个");
                String str = "";
                int iCount = values.length % 1000 == 0 ? values.length / 1000 : (values.length / 1000 + 1);
                for (int i = 0; i < iCount; i++) {
                    String strTemp = "";
                    int iCountTemp = (i == iCount - 1) ? values.length : 1000 * (i + 1);
                    for (int j = (0 + 1000 * i); j < iCountTemp; j++) {
                        Object value = values[j];
                        strTemp += ",'" + value + "'";
                    }
                    if (isContained) {
                        str += " OR " + fieldName + " IN (" + strTemp.substring(1) + ")";
                    } else {
                        str += " AND " + fieldName + " NOT IN (" + strTemp.substring(1) + ")";
                    }
                }
                sb.append(" (" + str.substring(4) + ")");
            } else {
                String str = "";
                for (Object value : values) {
                    str += ",'" + value + "'";
                }
                // 当values.length==0是防止substring溢出
                str = str.length() == 0 ? ",''" : str;
                if (isContained) {
                    sb.append(fieldName + " IN (" + str.substring(1) + ")");
                } else {
                    sb.append(fieldName + " NOT IN (" + str.substring(1) + ")");
                }
            }
        }
        return sb.toString();
    }

    public void addInSet(String fieldName, Set<?> values) {
        addInSet(fieldName, values, true);
    }

    public <T> void addInSet(Property<T, ?> property, Set<?> values) {
        addInSet(QueryManager.getFunctionName(property), values);
    }

    public void addInSet(String fieldName, Set<?> values, boolean isContained) {
        addInSet(fieldName, values.toArray(), isContained);
    }

    public <T> void addInSet(Property<T, ?> property, Set<?> values, boolean isContained) {
        addInSet(QueryManager.getFunctionName(property), values, isContained);
    }

    /**
     * 添加多对多的主键查询,少量数据时使用
     * 
     * @Title addM2MIdLink
     * @author 吕凯
     * @date 2019年8月14日 上午11:13:39
     * @param clazz
     * @param property
     * @param value
     *            关联对象relationTo的值 void
     */
    public <T> void addM2MIdLink(Class<T> clazz, Property<T, ?> property, Object value) {
        addM2MIdLink(clazz, property, value, null);
    }

    /**
     * 
     * 添加多对多的主键查询(in查询),少量数据时使用
     * 
     * @Title addM2MIdLink
     * @author 吕凯
     * @date 2019年8月19日 下午3:18:27
     * @param clazz
     * @param property
     * @param value
     * @param queryModel
     *            void
     */
    public <T> void addM2MIdLink(Class<T> clazz, Property<T, ?> property, Object value, QueryModel queryModel) {
        Field field;
        try {
            field = AnnotationUtil.getField(clazz, FunctionUtil.getFunctionName(property));
            if (field.isAnnotationPresent(Many2Many.class)) {
                Many2Many manyAnno = field.getAnnotation(Many2Many.class);
                String condition = " (SELECT " + manyAnno.relationFrom() + " FROM " + TableNameUtil.getTableName(manyAnno.relation())
                        + " WHERE " + manyAnno.relationTo() + "=? ";
                this.params.add(value);
                if (queryModel != null) {
                    String whereCnd = queryModel.getNoOrderQueryStrCondition(null);
                    if (StringUtils.isNotEmpty(whereCnd)) {
                        condition += "AND" + whereCnd;
                        Object[] whereQueryParams = queryModel.getParams();
                        if (whereQueryParams != null && whereQueryParams.length > 0) { // 参数存在
                            this.params.addAll(Arrays.asList(whereQueryParams));
                        }
                    }
                }
                condition += ") ";
                Condition cnd = new Condition(manyAnno.from(), Condition.Type.IN_STR, condition);
                cnds.add(cnd);
                this.condition += " AND " + manyAnno.from() + " IN " + condition;
            }
        } catch (Exception e) {
            log.error("", e);
        }
    }

    /**
     * 
     * 添加多对多的主键查询(exists查询),注意表的别名
     * 
     * @Title addM2MIdLinkByExists
     * @author 吕凯
     * @date 2019年8月19日 下午3:19:02
     * @param clazz
     * @param property
     * @param value
     * @param tableNameAlias
     *            void
     */
    public <T> void addM2MIdLinkByExists(Class<T> clazz, Property<T, ?> property, Object value, String tableNameAlias) {
        Field field;
        try {
            field = AnnotationUtil.getField(clazz, FunctionUtil.getFunctionName(property));
            if (field.isAnnotationPresent(Many2Many.class)) {
                Many2Many manyAnno = field.getAnnotation(Many2Many.class);
                this.condition += " AND EXISTS (SELECT " + manyAnno.relationFrom() + " FROM "
                        + TableNameUtil.getTableName(manyAnno.relation()) + " tpl WHERE tpl." + manyAnno.relationFrom() + "=";
                if (StringUtils.isNotBlank(tableNameAlias)) {
                    this.condition += tableNameAlias + ".";
                } else {
                    this.condition += TableNameUtil.getTableName(clazz) + ".";
                }
                this.condition += manyAnno.from() + " AND " + manyAnno.relationTo() + "=?) ";
                this.params.add(value);
            }
        } catch (Exception e) {
            log.error("", e);
        }
    }

    /**
     * 
     * 
     * 添加多对多的主键查询(exists查询),如果表的别名如果有误建议使用addM2MIdLinkByExists(Class<T> clazz, Property<T, ?> property, Object value, String
     * tableNameAlias)方法
     * 
     * @Title addM2MIdLinkByExists
     * @author 吕凯
     * @date 2019年9月19日 下午4:02:49
     * @param clazz
     * @param property
     * @param value
     *            void
     */
    public <T> void addM2MIdLinkByExists(Class<T> clazz, Property<T, ?> property, Object value) {
        addM2MIdLinkByExists(clazz, property, value, null);
    }

    public static void main(String[] args) {
        String ss = " and a= '123' and 1=1 and b='1'";
        QueryModel queryModel = new QueryModel();
        queryModel.addCondition(ss);
        QueryModel copy;
        try {
            copy = (QueryModel) queryModel.clone();
            System.out.println("00" + copy);
            String ss1 = " and b like  'test%'";
            queryModel.addCondition(ss1);
            System.out.println("00" + copy);
            System.out.println("11" + queryModel);
        } catch (CloneNotSupportedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void addCondition(String condition, Object... values) {
        Condition cnd = new Condition("", Condition.Type.SQL_STR, values);
        cnds.add(cnd);
        this.condition += " AND " + condition;
        if (values.length > 0) {
            for (Object v : values) {
                this.params.add(v);
            }
        }
    }

    public void addMultiCondition(boolean isOr, QueryModel... queryModels) {
        if (isOr) {
            addOrMultiCondition(queryModels);
        } else {
            addAndMultiCondition(queryModels);
        }
    }

    public void addAndMultiCondition(QueryModel... queryModels) {
        for (QueryModel tempQueryModel : queryModels) {
            String temp = tempQueryModel.getCondition();
            if (temp != null && !temp.isEmpty()) {
                condition += " AND " + temp;
                params.addAll(Arrays.asList(tempQueryModel.getParams()));
            }
        }
    }

    public void addOrMultiCondition(QueryModel... queryModels) {
        String tempCondition = "";
        for (QueryModel tempQueryModel : queryModels) {
            String temp = tempQueryModel.getCondition();
            if (temp != null && !temp.isEmpty()) {
                tempCondition += " OR (" + temp + ")";
                params.addAll(Arrays.asList(tempQueryModel.getParams()));
            }
        }
        condition += " AND (" + tempCondition.substring(4) + ")";
    }

    /**
     * 设置排序规则，如果之前设置过，该方法会重置，如果要追加使用addOrder方法
     * 
     * @Title setOrder
     * @author 吕凯
     * @date 2020年6月5日 下午6:13:58
     * @param fieldName
     * @param isDesc
     *            void
     */
    public void setOrder(String fieldName, boolean isDesc) {
        order = "";
        orders.clear();
        addOrder(fieldName, isDesc);
        /*order = " ORDER BY " + fieldName;
        if (isDesc) {
            order += " DESC";
        }*/
    }

    /**
     * 追加排序规则
     * 
     * @Title addOrder
     * @author 吕凯
     * @date 2020年6月2日 下午4:21:48
     * @param fieldName
     * @param isDesc
     *            void
     */
    public void addOrder(String fieldName, boolean isDesc) {
        if (fieldName.contains(",")) {
            log.warn("检测到排序字段名中使用了多个字符串，建议使用setOrder设置主排序字段addOrder增加副排序字段");
            Arrays.asList(fieldName.split(",")).forEach(order -> {
                String orderStr = order.trim().toLowerCase();
                boolean orderIsDesc = isDesc;
                if (orderStr.contains("desc")) {
                    orderIsDesc = true;
                    orderStr = StringUtils.substringBefore(orderStr, "desc");
                } else if (orderStr.contains("asc")) {
                    orderIsDesc = false;
                    orderStr = StringUtils.substringBefore(orderStr, "asc");
                }
                orderStr = orderStr.trim();
                Order orderTemp = new Order(orderStr, orderIsDesc);
                orders.add(orderTemp);
            });
        } else {
            Order order = new Order(fieldName, isDesc);
            orders.add(order);
        }
    }

    public <T> void addOrder(Property<T, ?> property, boolean isDesc) {
        addOrder(QueryManager.getFunctionName(property), isDesc);
    }

    public <T> void setOrder(Property<T, ?> property, boolean isDesc) {
        setOrder(QueryManager.getFunctionName(property), isDesc);
    }

    private String getCondition() {
        if (condition.isEmpty()) {
            return "";
        }
        return condition.substring(4);
    }

    /**
     * 此方法将被getNoOrderQueryStr(String tableAlias) 替代，下个版本删除
     * 
     * @Title getNoOrderQueryStr
     * @author 吕凯
     * @date 2019年8月16日 下午6:51:41
     * @return String
     */
    @Deprecated
    public String getNoOrderQueryStr() {
        if (condition.isEmpty()) {
            return "";
        }
        return " WHERE" + condition.substring(4);
    }

    public String getNoOrderQueryStr(String tableAlias) {
        if (condition.isEmpty()) {
            return "";
        }
        return " WHERE" + getNoOrderQueryStrCondition(tableAlias);
    }

    /**
     * 此方法将被getNoOrderQueryStr(String tableAlias) 替代，下个版本删除
     * 
     * @Title getOrderQueryStr
     * @author 吕凯
     * @date 2019年8月16日 下午6:51:41
     * @return String
     */
    @Deprecated
    public String getOrderQueryStr() {
        return getNoOrderQueryStr() + getOrder(null);
    }

    public String getOrderQueryStr(String tableAlias) {
        return getNoOrderQueryStr(tableAlias) + getOrder(null);
    }

    public String getOrder(String tableAlias) {
        if (StringUtils.isEmpty(order)) {
            StringBuffer sb = new StringBuffer();
            boolean isFirst = true;
            for (Order order : orders) {
                if (!isFirst) {
                    sb.append(",");
                }
                if (StringUtils.isNotEmpty(tableAlias)) {
                    sb.append(tableAlias).append(".");
                }
                sb.append(order.getColumn()).append(order.getIsDesc() ? " DESC" : "");
                isFirst = false;
            }
            if (sb.length() > 0) {
                sb.insert(0, " ORDER BY ");
            }
            order += sb.toString();
        }
        return order;
    }

    public Object[] getParams() {
        return params.toArray();
    }

    public String getSelectFields() {
        return selectFields;
    }

    public void setSelectFields(String selectFields) {
        this.selectFields = selectFields;
    }

    public <T> void setSelectFields(Property<T, ?> property) {
        setSelectFields(QueryManager.getFunctionName(property));
    }

    /**
     * 添加查询添加sql,以and开头,使用getNoOrderQueryStrCondition(String tableAlias)替代，下次升级将删除此方法
     * 
     * @return
     * @author 玄承勇
     * @date 2014-6-30 上午9:35:30
     */
    @Deprecated
    public String getNoOrderQueryStrCondition() {
        if (condition.isEmpty()) {
            return "";
        }
        return " AND " + condition.substring(4);
    }

    public String getNoOrderQueryStrCondition(String tableAlias) {
        StringBuffer sb = new StringBuffer();
        cnds.stream()/*.filter(cnd -> cnd.getQueryType() != Cnd.Type.ORDER)*/.forEach(cnd -> {
            String colunmName = cnd.getColumn();
            sb.append(" AND ");
            if (StringUtils.isNotEmpty(colunmName)) {
                if (StringUtils.isNotEmpty(tableAlias)) {
//                    sb.append(tableAlias).append(".");
                    colunmName = tableAlias + "." + colunmName;
                }
                if (cnd.getQueryType() != Condition.Type.IN_SET) { // inset需要单独处理
                    sb.append(colunmName);
                }
            }
            // 每个条件前面加空格，后面不加
            if (cnd.getQueryType() == Condition.Type.EQUAL) {
                if (cnd.getValues() == null) {
                    sb.append(" IS NULL");
                } else {
                    sb.append(" = ").append("?");
                }
            } else if (cnd.getQueryType() == Condition.Type.NOT_EQUAL) {
                if (cnd.getValues() == null) {
                    sb.append(" IS NOT NULL");
                } else {
                    sb.append(" != ").append("?");
                }
            } else if (cnd.getQueryType() == Condition.Type.GT) {
                sb.append(" > ").append("?");
            } else if (cnd.getQueryType() == Condition.Type.GE) {
                sb.append(" >= ").append("?");
            } else if (cnd.getQueryType() == Condition.Type.LT) {
                sb.append(" < ").append("?");
            } else if (cnd.getQueryType() == Condition.Type.LE) {
                sb.append(" <= ").append("?");
            } else if (cnd.getQueryType() == Condition.Type.LIKE || cnd.getQueryType() == Condition.Type.LIKE_LEFT
                    || cnd.getQueryType() == Condition.Type.LIKE_RIGHT) {
                sb.append(" LIKE ").append("?");
            } else if (cnd.getQueryType() == Condition.Type.BETWEEN) {
                sb.append(" BETWEEN ").append("?").append(" and ").append("?");
            } else if (cnd.getQueryType() == Condition.Type.IN_STR) {
                sb.append(" IN ( ").append(cnd.getValues()).append(" )");
            } else if (cnd.getQueryType() == Condition.Type.IN_SET) { // TODO 略麻烦
                sb.append(getInStr(colunmName, (Object[]) cnd.getValues(), true));
            }
        });
        String queryStr = sb.toString();
        if (queryStr.startsWith(" AND ")) { // 如果以AND 开头，表示主表没有查询条件，需要将第一个AND替换掉
            queryStr = queryStr.replaceFirst(" AND ", " ");
        }
        return queryStr;
    }

    public void addLimit(int value) {
        condition += " LIMIT " + value;
    }

    /**
     * 重新clone方法
     * 
     * @Title clone
     * @author xx
     * @date 2013年7月26日 下午1:46:40
     * @return
     * @throws CloneNotSupportedException
     * @see java.lang.Object#clone()
     */
    @Override
    public Object clone() throws CloneNotSupportedException {

        QueryModel cloneObj = null;
        try {
            cloneObj = (QueryModel) super.clone();
            List<Object> list = new ArrayList<>(this.params);
            cloneObj.params = list;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return cloneObj;
    }

    public Boolean getQueryLink() {
        return queryLink;
    }

    public void setQueryLink(Boolean queryLink) {
        this.queryLink = queryLink;
    }

    public List<Property<?, ?>> getQueryLinkFields() {
        return queryLinkFields;
    }

    /**
     * 添加参数
     * 
     * @Title addQueryField
     * @author 吕凯
     * @date 2019年7月26日 下午1:47:09
     * @param clazz
     * @param property
     *            void
     */
    public <T> void addQueryField(Property<T, ?> property) {
        if (queryLinkFields == null) {
            queryLinkFields = new ArrayList<>();
        }
        if (!queryLinkFields.contains(property)) {
            queryLinkFields.add(property);
        }
    }

    public <T> void clearQueryField() {
        if (queryLinkFields != null) {
            queryLinkFields.clear();
        }
    }

    public QueryModel copy() {
        QueryModel newObj = new QueryModel();
        newObj.setSelectFields(getSelectFields());
        newObj.setCondition(this.condition);
        newObj.setOrder(getOrder());
        newObj.setQueryLink(getQueryLink()); // 查询级联对象
        newObj.setQueryLinkFields(getQueryLinkFields()); // 查询哪些级联对象，如果queryLink为true此项不设置默认查询model中配置了@Link注解的
        newObj.setParams(this.params);
        newObj.setCnds(getCnds());// 条件
        newObj.setOrders(getOrders());// 排序
        newObj.setJoinTableAlias(getJoinTableAlias()); // 用于join查询用,表别名
        newObj.setJoinType(getJoinType()); // join类型
        return newObj;
    }

//    public static void main(String[] args) {
//        QueryModel queryModel = new QueryModel();
//        queryModel.addEq(QueryModel.class, QueryModel::getCondition, 1); //
//    }

}
